#include <gtest/gtest.h>
#include <market_data/market_data_storage.h>
#include <market_data/csv_storage.h>
#include <market_data/async_storage.h>
#include <fstream>
#include <filesystem>
#include <thread>
#include <chrono>

using namespace hft;
using namespace std::chrono;

class MarketDataStorageTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 创建测试目录
        testDir = "test_data/market_data_storage_test";
        std::filesystem::create_directories(testDir);
        
        // 创建测试数据
        testData.symbol = "IF2309";
        testData.exchange = "CFFEX";
        testData.lastPrice = 3500.0;
        testData.volume = 10000;
        testData.turnover = 35000000.0;
        testData.openInterest = 5000;
        testData.bidPrice1 = 3499.8;
        testData.bidVolume1 = 10;
        testData.askPrice1 = 3500.2;
        testData.askVolume1 = 15;
        testData.timestamp = system_clock::now();
    }

    void TearDown() override {
        // 清理测试目录
        std::filesystem::remove_all(testDir);
    }

    std::string testDir;
    MarketData testData;
};

TEST_F(MarketDataStorageTest, CsvStorageBasic) {
    // 创建CSV存储
    std::string filePath = testDir + "/IF2309.csv";
    CsvStorage storage(filePath);
    
    // 存储数据
    EXPECT_TRUE(storage.store(testData));
    
    // 验证文件是否创建
    EXPECT_TRUE(std::filesystem::exists(filePath));
    
    // 读取文件内容并验证
    std::ifstream file(filePath);
    ASSERT_TRUE(file.is_open());
    
    std::string header;
    std::getline(file, header);
    
    // 验证CSV头部
    EXPECT_TRUE(header.find("symbol") != std::string::npos);
    EXPECT_TRUE(header.find("lastPrice") != std::string::npos);
    EXPECT_TRUE(header.find("volume") != std::string::npos);
    
    // 验证数据行
    std::string dataLine;
    std::getline(file, dataLine);
    EXPECT_TRUE(dataLine.find("IF2309") != std::string::npos);
    EXPECT_TRUE(dataLine.find("3500") != std::string::npos);
    EXPECT_TRUE(dataLine.find("10000") != std::string::npos);
    
    file.close();
}

TEST_F(MarketDataStorageTest, CsvStorageMultipleRecords) {
    // 创建CSV存储
    std::string filePath = testDir + "/multiple.csv";
    CsvStorage storage(filePath);
    
    // 存储多条数据
    for (int i = 0; i < 5; ++i) {
        MarketData data = testData;
        data.lastPrice += i * 0.2;  // 每次价格增加0.2
        data.volume += i * 100;     // 每次成交量增加100
        EXPECT_TRUE(storage.store(data));
    }
    
    // 验证文件是否创建
    EXPECT_TRUE(std::filesystem::exists(filePath));
    
    // 读取文件内容并验证行数
    std::ifstream file(filePath);
    ASSERT_TRUE(file.is_open());
    
    int lineCount = 0;
    std::string line;
    while (std::getline(file, line)) {
        lineCount++;
    }
    
    // 应该有1行头部 + 5行数据
    EXPECT_EQ(lineCount, 6);
    
    file.close();
}

TEST_F(MarketDataStorageTest, AsyncStorageBasic) {
    // 创建异步存储
    std::string filePath = testDir + "/async.csv";
    auto csvStorage = std::make_shared<CsvStorage>(filePath);
    AsyncStorage asyncStorage(csvStorage);
    
    // 启动异步存储
    asyncStorage.start();
    
    // 存储数据
    EXPECT_TRUE(asyncStorage.store(testData));
    
    // 等待异步处理完成
    std::this_thread::sleep_for(milliseconds(100));
    
    // 停止异步存储
    asyncStorage.stop();
    
    // 验证文件是否创建
    EXPECT_TRUE(std::filesystem::exists(filePath));
    
    // 读取文件内容并验证
    std::ifstream file(filePath);
    ASSERT_TRUE(file.is_open());
    
    std::string header;
    std::getline(file, header);
    
    // 验证CSV头部
    EXPECT_TRUE(header.find("symbol") != std::string::npos);
    
    // 验证数据行
    std::string dataLine;
    std::getline(file, dataLine);
    EXPECT_TRUE(dataLine.find("IF2309") != std::string::npos);
    
    file.close();
}

TEST_F(MarketDataStorageTest, AsyncStoragePerformance) {
    // 创建异步存储
    std::string filePath = testDir + "/perf.csv";
    auto csvStorage = std::make_shared<CsvStorage>(filePath);
    AsyncStorage asyncStorage(csvStorage);
    
    // 设置队列大小和刷新间隔
    asyncStorage.setMaxQueueSize(1000);
    asyncStorage.setFlushInterval(milliseconds(50));
    
    // 启动异步存储
    asyncStorage.start();
    
    // 记录开始时间
    auto start = high_resolution_clock::now();
    
    // 存储大量数据
    const int dataCount = 1000;
    for (int i = 0; i < dataCount; ++i) {
        MarketData data = testData;
        data.lastPrice += i * 0.01;
        data.volume += i;
        EXPECT_TRUE(asyncStorage.store(data));
    }
    
    // 记录结束时间
    auto end = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(end - start);
    
    // 输出性能信息
    std::cout << "Stored " << dataCount << " records in " 
              << duration.count() << " ms" << std::endl;
    
    // 等待异步处理完成
    std::this_thread::sleep_for(milliseconds(200));
    
    // 停止异步存储
    asyncStorage.stop();
    
    // 验证文件是否创建
    EXPECT_TRUE(std::filesystem::exists(filePath));
    
    // 读取文件内容并验证行数
    std::ifstream file(filePath);
    ASSERT_TRUE(file.is_open());
    
    int lineCount = 0;
    std::string line;
    while (std::getline(file, line)) {
        lineCount++;
    }
    
    // 应该有1行头部 + dataCount行数据
    EXPECT_EQ(lineCount, dataCount + 1);
    
    file.close();
}

TEST_F(MarketDataStorageTest, AsyncStorageQueueFull) {
    // 创建异步存储，设置很小的队列大小
    std::string filePath = testDir + "/queue_full.csv";
    auto csvStorage = std::make_shared<CsvStorage>(filePath);
    AsyncStorage asyncStorage(csvStorage);
    
    // 设置小队列大小和较长的刷新间隔
    asyncStorage.setMaxQueueSize(10);
    asyncStorage.setFlushInterval(milliseconds(500));
    
    // 启动异步存储
    asyncStorage.start();
    
    // 尝试存储超过队列容量的数据
    bool allStored = true;
    for (int i = 0; i < 20; ++i) {
        MarketData data = testData;
        data.lastPrice += i;
        if (!asyncStorage.store(data)) {
            allStored = false;
        }
    }
    
    // 应该有些数据无法存储（队列已满）
    EXPECT_FALSE(allStored);
    
    // 等待异步处理完成
    std::this_thread::sleep_for(milliseconds(600));
    
    // 停止异步存储
    asyncStorage.stop();
}